<template>
	<div class="rule-detain-page h-full flex">
		<div class="h-full" style="width: 200px">
			<div class="text-base font-bold data-title">输入</div>
			<div id="input-palette" class="palette"></div>

			<div class="text-base font-bold data-title mt-8">处理</div>
			<div id="calc-palette" class="palette"></div>

			<div class="text-base font-bold data-title mt-8">输出</div>
			<div id="error-palette" class="palette"></div>
			<div id="output-palette" class="palette"></div>
		</div>
		<div class="flex-1 pl-8">
			<div class="text-base font-bold data-title flex justify-between pb-2">
				<span>规则编排</span>
				<el-button type="primary" @click="save">保存</el-button>
			</div>
			<div id="myDiagramDiv" class="myDiagramDiv" :style="{ height: `calc(100% - 33% - 40px)` }"></div>

			<div class="h-1/3 pt-8 form-info">
				<div class="text-base font-bold pb-2 flex justify-between items-center">
					<div>参数配置</div>
					<el-button type="primary" @click="save">保存</el-button>
				</div>
				<el-form class="flex flex-wrap flex-row" label-width="80px">
					<el-form-item label="节点">
						<el-select v-model="nodeParam.name" placeholder="节点名称"> </el-select>
					</el-form-item>
					<el-form-item label="设备">
						<el-select v-model="nodeParam.input.sn" placeholder="请选择设备"> </el-select>
					</el-form-item>
					<el-form-item label="变量">
						<el-select v-model="nodeParam.input.sensor" placeholder="请选择设备"> </el-select>
					</el-form-item>
					<div class="w-full">
						<el-form-item label="处理" style="margin-bottom: 0">
							<el-input type="textarea" v-model="nodeParam.calc" :rows="6" />
						</el-form-item>
					</div>
					<!-- <el-form-item label="输出">
						<el-select v-model="nodeParam.output" placeholder="请选择输出"> </el-select>
					</el-form-item> -->
				</el-form>
			</div>
		</div>
	</div>
</template>

<!-- eslint-disable no-var -->
<!-- eslint-disable @typescript-eslint/no-this-alias -->
<!-- eslint-disable @typescript-eslint/no-unused-vars -->
<script lang="ts">
import go from "gojs";
import { ShapeParam } from "./interface";
const $ = go.GraphObject.make;
export default {
	data() {
		return {
			nodeParam: {
				name: "",
				input: {
					sn: "",
					sensor: ""
				},
				calc: "",
				output: ""
			},
			nodeData: [
				{ category: "input", text: "\u8bbe\u5907\u6e29\u5ea6", key: 1, loc: "-290.1891109793485 -104.42790309325116" },
				{ category: "calc", text: "\u683c\u5f0f\u8f6c\u6362", key: 2, loc: "-9.072825411053117 -104.22219986325449" },
				{
					category: "output",
					text: "\u8f93\u51fa\u5230\u6570\u636e\u5e93",
					key: 3,
					loc: "253.03951917444704 -225.5230212385675"
				},
				{ category: "error", text: "\u5f02\u5e38\u56de\u8c03", key: 4, loc: "249.35330136873245 21.935161240123087" }
			],
			linkData: [
				{ from: 1, to: 2 },
				{ from: 2, to: 3 },
				{ from: 2, to: 4 }
			]
		};
	},

	mounted() {
		this.init();
	},
	methods: {
		save() {
			var mySelf = this as any;
			console.log(mySelf.myDiagram.model.toJson());
			mySelf.myDiagram.isModified = false;
		},
		init() {
			class DemoForceDirectedLayout extends go.ForceDirectedLayout {
				//布局
				makeNetwork(coll: any) {
					const net = super.makeNetwork(coll);
					net.vertexes.each((vertex: any) => {
						const node = vertex.node;
						if (node !== null) vertex.isFixed = node.isSelected;
					});
					return net;
				}
			}
			var mySelf = this as any;

			mySelf.myDiagram = $(
				go.Diagram,
				"myDiagramDiv", // 为DIV.HTML元素创建一个画布
				{
					//设置画布配置
					initialContentAlignment: go.Spot.Center, // 居中显示
					"undoManager.isEnabled": true, // 支持 Ctrl-Z 和 Ctrl-Y 操作
					"toolManager.hoverDelay": 100, //tooltip提示显示延时
					"toolManager.toolTipDuration": 10000, //tooltip持续显示时间
					//isReadOnly:true,//只读
					"grid.visible": false, //显示网格
					allowMove: true, //允许拖动
					allowDragOut: true,
					allowDelete: true,
					allowCopy: true,
					allowClipboard: true,
					doubleClick: null,
					initialAutoScale: go.Diagram.Uniform, // 缩放以使所有内容都适合

					"toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, //有鼠标滚轮事件放大和缩小，而不是向上和向下滚动
					// "clickCreatingTool.archetypeNodeData": { category: "calc", text: "新节点", notice: "" }, // 双击新建节点(可以写入节点的默认信息)；
					layout: new DemoForceDirectedLayout()
				}
			);

			mySelf.myDiagram.linkTemplate = $(
				go.Link,
				{
					routing: go.Link.Orthogonal,
					corner: 15,
					selectable: true, //连接线是否可选
					relinkableFrom: true, //出发点是否可以改变
					relinkableTo: true //目标点是否可以改变
				},
				new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
				$(go.Shape, {
					strokeWidth: 2, //节点连接线宽度
					stroke: "#F60" //颜色
				}),
				$(go.Shape, {
					toArrow: "Standard",
					fill: "#F60", //箭头填充色
					stroke: "#F60" //外边框颜色
				}), // 箭头
				$(
					go.TextBlock,
					{
						margin: 20,
						stroke: "blue",
						font: "14px sans-serif",
						// width: 40,
						wrap: go.TextBlock.WrapDesiredSize
					},
					new go.Binding("text", "text")
				),
				{
					toolTip: $(
						go.Adornment,
						"Auto",
						$(go.Shape, {
							fill: "#FFFFCC"
						}),
						$(
							go.TextBlock,
							{
								margin: 4
							},
							new go.Binding("text", "text")
						)
					) // end of Adornment
				}
			);
			//定义输入节点
			mySelf.myDiagram.nodeTemplateMap.add(
				"input",
				$(
					go.Node,
					"auto",
					mySelf.getNodeOption(),
					new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
					//创建节点面板
					mySelf.markerNode(),
					//设置节点扩展（提供一个输出）
					mySelf.markerNodeExt(new go.Margin(0, 0, 0, 177)),
					//悬浮提示
					mySelf.markerTooltip()
				)
			);
			//定义处理节点
			mySelf.myDiagram.nodeTemplateMap.add(
				"calc",
				$(
					go.Node,
					"auto",
					mySelf.getNodeOption(),
					new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
					//创建节点面板
					mySelf.markerNode({ color: "orange" }),
					//设置节点扩展（提供一组输入与输出）
					mySelf.markerNodeExt(),
					mySelf.markerNodeExt(new go.Margin(0, 0, 0, 177)),
					//悬浮提示
					mySelf.markerTooltip()
				)
			);
			//定义错误节点
			mySelf.myDiagram.nodeTemplateMap.add(
				"error",
				$(
					go.Node,
					"auto",
					mySelf.getNodeOption(),
					new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
					//创建节点面板
					mySelf.markerNode({ color: "red" }),
					//设置节点扩展（提供一个输入，没有输出）
					mySelf.markerNodeExt(new go.Margin(3, 0, 0, 0), { height: 56 }),
					//悬浮提示
					mySelf.markerTooltip()
				)
			);
			//定义输出节点
			mySelf.myDiagram.nodeTemplateMap.add(
				"output",
				$(
					go.Node,
					"auto",
					mySelf.getNodeOption(),
					new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
					//创建节点面板
					mySelf.markerNode(),
					//设置节点扩展（提供一个输入，没有输出）
					mySelf.markerNodeExt(),
					//悬浮提示
					mySelf.markerTooltip()
				)
			);
			//填充默认数据
			mySelf.myDiagram.model.nodeDataArray = mySelf.nodeData;
			mySelf.myDiagram.model.linkDataArray = mySelf.linkData;
			//添加左侧面板
			mySelf.initPalette();
			//添加事件
			mySelf.initEvent();
		},
		initEvent() {
			var mySelf = this as any;
			// 单击节点事件
			mySelf.myDiagram.addDiagramListener("ObjectSingleClicked", (e: any) => {
				const node = e.subject.part.data;
				this.nodeParam.name = node.text;
				this.nodeParam.calc = node.text;
				this.nodeParam.input = node.key;
				console.log(node);
			});

			// 双击节点事件
			mySelf.myDiagram.addDiagramListener("ObjectDoubleClicked", (e: any) => {
				const node = e.subject.part.data;
			});

			//图表完成更新事件
			mySelf.myDiagram.addDiagramListener("Modified", (e: any) => {
				//监听画布是否修改
				//todo change save button status.
			});

			//双击画布
			mySelf.myDiagram.addDiagramListener("BackgroundDoubleClicked", (e: any) => {});
		},
		getNodeOption() {
			return {
				movable: true, //是否可拖动
				deletable: true, //是否可删除
				selectable: true, //是否可选择
				selectionAdorned: true //显示选中边框
				// reshapable:true, // 重塑(改变shape形状边界时使用，将影响节点大小)
				// resizable: true, // 可调整大小的(手动调整节点大小时，节点内容显示区域时使用)
			};
		},
		markerNode(param?: ShapeParam, type?: "input" | "calc" | "output") {
			let mySelf = this as any;
			return $(
				go.Panel, //表明需要创建一个panel面板对象//声明创建一个新的面板对象,自定义方式可参考mySelf.myDiagram.nodeTemplate
				"Auto", //页面布局为自动
				$(
					go.Shape, //声明构建一个圆形
					"RoundedRectangle",
					mySelf.markerNodeFull(param),
					new go.Binding("figure", "figure") //声明并创建一个新的图形
				),
				//节点文字
				mySelf.markerNodeText(param)
			);
		},
		markerNodeExt(margin: go.Margin, param?: ShapeParam) {
			return $(go.Shape, "Rectangle", { width: 5, height: param?.height || 60, margin: margin || 0, fill: "green" });
		},
		markerNodeText() {
			return $(
				go.TextBlock,
				{
					//声明一个可编辑文本域
					maxSize: new go.Size(360, NaN),
					wrap: go.TextBlock.WrapFit, //文本域换行
					editable: true //是否可编辑
				},
				new go.Binding("text").makeTwoWay()
			);
		},
		markerNodeFull(param: ShapeParam) {
			param = param || {};
			return {
				fill: param.color || "#e8e8e8", //内填充色
				cursor: "pointer", //指针
				stroke: param.border || "#ccc", //外框颜色
				strokeWidth: 3, //边框宽度
				portId: "",
				fromLinkable: true,
				fromLinkableSelfNode: false,
				fromLinkableDuplicates: true,
				toLinkable: true,
				toLinkableSelfNode: false,
				toLinkableDuplicates: true,
				width: param.width || 180,
				height: param.height || 60
			};
		},
		markerTooltip() {
			return {
				toolTip: $("ToolTip", $(go.TextBlock, { margin: 4 }, new go.Binding("text", "text")))
			};
		},
		initPalette() {
			var mySelf = this as any;
			let type = [
				{ category: "input", el: "input-palette", label: "收到数据", type: "input" },
				{ category: "calc", el: "calc-palette", label: "数据转换", type: "calc" },
				{ category: "output", el: "output-palette", label: "输出结果", type: "output" },
				{ category: "error", el: "error-palette", label: "输出错误", type: "output" }
			];
			type.forEach(item => {
				$(
					go.Palette,
					item.el || `${item.category}-palette`, // 必须命名或引用DIV.HTML元素
					{
						scrollsPageOnFocus: false,
						nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap, // 共享myDiagram使用的模板
						model: new go.GraphLinksModel([
							{
								category: item.category,
								text: item.label
							}
						])
					}
				);
			});
		}
	}
};
</script>

<style lang="scss">
.rule-detain-page {
	height: 100%;
	.myDiagramDiv {
		border: 1px solid #cccccc;
	}
	.data-title {
		display: flex;
		align-items: center;
		padding-left: 10px;
	}
	.palette {
		height: 75px;
	}
	.form-info {
		box-sizing: border-box;
		.el-form {
			box-sizing: border-box;
			padding: 15px;
			border: 1px solid #cccccc;
		}
	}
}
</style>
